
/'
	
	FB.Strings - Various string functions for FreeBASIC


	Note: portions of code below are translated from:
	
			- D language (from Phobos library) 
	      - C language (from php language)
	
'/

#Define __FB_STRINGS_NO_INCLIB__
#Include "../inc/fbstrings.bi"

#Include "crt/string.bi"

#Define C_TAB 	 9
#Define C_CR	13
#Define C_LF	10

Namespace FB.Strings
	
	Function StrReplace(	ByRef pSource As Const String													,_
								ByRef pFind As Const String													,_
								ByRef pReplaceWith As Const String											,_
								ByRef pReplacedCount As Integer = 0											,_
								ByVal pMaxReplacements As Const Integer = 0								,_
								ByVal pCompare As Const CompareMethod = BinaryCompare					)_
								As String
	'{		
		Dim As Integer iPos, iReplacementLength, iFindLength
		Dim As String sRet, sTemp, sFind, sReplaceWith
		
		If pCompare = TextCompare Then
			sFind = LCase(pFind)
			sTemp = LCase(pSource)
			sReplaceWith = LCase(pReplaceWith)
		Else
			sFind = pFind
			sTemp = pSource
			sReplaceWith = pReplaceWith
		EndIf
		
		sRet = pSource		
		pReplacedCount = 0
		iReplacementLength = Len(pReplaceWith)
		iPos = 1 - iReplacementLength
		iFindLength = Len(pFind)
		
		Do
			
			iPos = InStr(iPos + iReplacementLength, sTemp, sFind)
			
			If iPos = 0 Then Exit Do
			
			sRet = Left(sRet, iPos - 1) + pReplaceWith + Right(sRet, Len(sRet) - iPos - iFindLength + 1)
			sTemp = Left(sTemp, iPos - 1) + sReplaceWith + Right(sTemp, Len(sTemp) - iPos - iFindLength + 1)
			
			pReplacedCount += 1
			
			If pReplacedCount = pMaxReplacements Then Exit Do
			
		Loop
		
		Return sRet
	'}	
	End Function
	
	Function StrReplace(	ByRef pSource As String															,_
								pFind() As String																	,_
								pReplaceWith() As String														,_
								ByRef pReplacedCount As Integer = 0											,_
								ByVal pMaxReplacements As Const Integer = 0								,_
								ByVal pCompare As Const CompareMethod = BinaryCompare					)_
								As String
	'{	
		Dim As Const Integer lbFind = LBound(pFind)						, _
									lbReplaceWith = LBound(pReplaceWith)
									
		Dim As Const Integer sizeFind = UBound(pFind) - lbFind + 1								, _
									sizeReplaceWith = UBound(pReplaceWith) - lbReplaceWith + 1
		
		Dim As String sRet = pSource
		
		If sizeFind <> sizeReplaceWith Then Return sRet
		
		Dim As Integer iPos, iPosMin, iPosTemp, iLastReplacementLength, index
		Dim As String sTemp, sFind(0 To sizeFind - 1), sReplaceWith(0 To sizeFind - 1)
		
		If pCompare = TextCompare Then
			For i As Integer = 0 To sizeFind - 1
				sFind(i) = LCase(pFind(lbFind + i))
				sReplaceWith(i) = LCase(pReplaceWith(lbReplaceWith + i))
			Next
			sTemp = LCase(pSource)
		Else
			For i As Integer = 0 To sizeFind - 1
				sFind(i) = pFind(lbFind + i)
				sReplaceWith(i) = pReplaceWith(lbReplaceWith + i)
			Next
			sTemp = pSource
		EndIf
		
		pReplacedCount = 0
		iLastReplacementLength = 0
		iPosMin = 0
		iPos = 1
		
		Do
			For i As Integer = 0 To sizeFind - 1
				iPosTemp = InStr(iPos, sTemp, sFind(i))
				If ((iPosTemp < iPosMin) AndAlso (iPosTemp > 0)) OrElse (iPosMin = 0) Then 
					iPosMin = iPosTemp
					index = i
				EndIf
			Next
			
			If iPosMin = 0 Then Exit Do
			
			iPos = iPosMin
			iPosMin = 0 
			
			sRet = Left(sRet, iPos - 1) + pReplaceWith(lbReplaceWith + index) + Right(sRet, Len(sRet) - iPos - Len(sFind(index)) + 1)
			sTemp = Left(sTemp, iPos - 1) + sReplaceWith(index) + Right(sTemp, Len(sTemp) - iPos - Len(sFind(index)) + 1)
			
			iPos += Len(sReplaceWith(index))
			
			pReplacedCount += 1
			
			If pReplacedCount = pMaxReplacements Then Exit Do
			
		Loop
		
		Return sRet
	'}	
	End Function
	
	Function StrReplace(	ByRef pSource As String															,_
								pFind() As String																	,_
								ByRef pReplaceWith As String													,_
								ByRef pReplacedCount As Integer = 0											,_
								ByVal pMaxReplacements As Const Integer = 0								,_
								ByVal pCompare As Const CompareMethod = BinaryCompare					)_
								As String
	'{				
		Dim As Integer iPos, iPosMin, iPosTemp, iReplacementLength, index
		Dim As String sRet = pSource, sTemp, sFind(LBound(pFind) To UBound(pFind)), sReplaceWith
		
		If pCompare = TextCompare Then
			For i As Integer = LBound(pFind) To UBound(pFind)
				sFind(i) = LCase(pFind(i))
			Next
			sReplaceWith = LCase(pReplaceWith)
			sTemp = LCase(pSource)
		Else
			For i As Integer = LBound(pFind) To UBound(pFind)
				sFind(i) = pFind(i)
			Next
			sReplaceWith = pReplaceWith
			sTemp = pSource
		EndIf
		
		pReplacedCount = 0
		iReplacementLength = Len(sReplaceWith)
		iPosMin = 0
		iPos = 1
		
		Do
			For i As Integer = LBound(sFind) To UBound(sFind)
				iPosTemp = InStr(iPos, sTemp, sFind(i))
				If ((iPosTemp < iPosMin) AndAlso (iPosTemp > 0)) OrElse (iPosMin = 0) Then 
					iPosMin = iPosTemp
					index = i
				EndIf
			Next
			
			If iPosMin = 0 Then Exit Do
			
			iPos = iPosMin
			iPosMin = 0 
			
			sRet = Left(sRet, iPos - 1) + pReplaceWith + Right(sRet, Len(sRet) - iPos - Len(sFind(index)) + 1)
			sTemp = Left(sTemp, iPos - 1) + sReplaceWith + Right(sTemp, Len(sTemp) - iPos - Len(sFind(index)) + 1)
			
			iPos += iReplacementLength
			
			pReplacedCount += 1
			
			If pReplacedCount = pMaxReplacements Then Exit Do
			
		Loop
		
		Return sRet
	'}	
	End Function
	
	Function StrReplace(	pSource() As String																,_
								pFind() As String																	,_
								pReplaceWith() As String														,_
								pResult() As String																,_
								ByRef pReplacedCount As Integer = 0											,_
								ByVal pMaxReplacements As Const Integer = 0								,_
								ByVal pCompare As Const CompareMethod = BinaryCompare					)_
								As Integer
	'{	
		Dim As Const Integer lbSource = LBound(pSource)					, _
									lbFind = LBound(pFind)						, _
									lbReplaceWith = LBound(pReplaceWith)
									
		Dim As Const Integer sizeSource = UBound(pSource) - lbSource + 1						, _
									sizeFind = UBound(pFind) - lbFind + 1								, _
									sizeReplaceWith = UBound(pReplaceWith) - lbReplaceWith + 1 
		
		If (sizeSource <> sizeFind) OrElse (sizeFind <> sizeReplaceWith) Then Return 0
		
		ReDim pResult(0 To sizeSource - 1) As String
		
		For i As Integer = 0 To sizeSource - 1
			
			pResult(i) = StrReplace(												 _
												pSource(lbSource + i)				,_
												pFind(lbFind + i)						,_
												pReplaceWith(lbReplaceWith + i)	,_
												pReplacedCount							,_
												pMaxReplacements						,_
												pCompare									 )
		Next
		
		Return sizeSource - 1
	'}	
	End Function
	
	
	Function StrReverse(	ByRef pString As Const String ) As String
	'{	
		Dim As String sRet = String(Len(pString), Chr(0))
		Dim As Integer length = Len(pString) - 1
		
		For i As Integer = 0 To length
			sRet[i] = pString[length - i]
		Next
		
		Return sRet
	'}	
	End Function
	
	
	Function StrAlignLeft(	ByRef pString As Const String												,_
									ByVal pSize As Const Integer												,_
									ByRef pPadWith As Const String = " "									)_
									As String
	'{								
		If pSize > Len(pString) Then Return pString + String(pSize - Len(pString), pPadWith)
		
		Return pString
	'}	
	End Function
	
	
	Function StrAlignRight(	ByRef pString As Const String												,_
									ByVal pSize As Const Integer												,_
									ByRef pPadWith As Const String = " "									)_
									As String
	'{								
		If pSize > Len(pString) Then Return String(pSize - Len(pString), pPadWith) + pString
		
		Return pString
	'}	
	End Function
	
	
	Function StrAlignCenter( ByRef pString As Const String											,_
									 ByVal pSize As Const Integer												,_
									 ByRef pPadWith As Const String = " "									)_
									 As String
	'{								
		If pSize > Len(pString) Then
			
			Dim As Integer numLeft = (pSize - Len(pString)) \ 2
			
			Return String(numLeft, pPadWith) + pString + String(pSize - numLeft - Len(pString), pPadWith)
			
		EndIf
		
		Return pString
	'}	
	End Function
	
	
	Function StrRepeat(	ByRef pString As Const String													,_
								ByVal pRepeatCount As Const Integer											)_
								As String
	'{	
		If Len(pString) = 1 Then Return String(pRepeatCount, pString)
		
		Dim As Const Integer length = Len(pString)
		Dim As String sRet = String(length * pRepeatCount, 0)
		
		For i As Integer = 0 To pRepeatCount - 1 
			Mid(sRet, length * i + 1) = pString
		Next
		
		Return sRet
	'}	
	End Function
	
	
	Function StrCount(	ByRef pString As Const String													,_
								ByRef pSubString As Const String												,_
								ByVal pCompare As Const CompareMethod = BinaryCompare					)_
								As Integer
	'{	
		Dim As Integer iRet = 0, iPos
		Dim As Const Integer iSubStringLength = Len(pSubString)
		Dim As String sString, sSubString
		
		If pCompare = TextCompare Then
			sString = LCase(pString)
			sSubString = LCase(pSubString)
		Else
			sString = pString
			sSubString = pSubString
		EndIf
		
		iPos = 1 - iSubStringLength
		
		Do
			
			iPos = InStr(iPos + iSubStringLength, sString, sSubString)
			
			If iPos = 0 Then Exit Do
			
			iRet += 1
			
		Loop
		
		Return iRet
	'}	
	End Function
	
	
	Function StrInPattern(	ByVal pCharacter As Const Ubyte											,_
									ByRef pPattern As Const String											)_
									As Integer
	'{	
		Dim As Integer bRet = 0, inRange = 0
		Dim As UByte char, lastChar
		
		For i As Integer = 0 To Len(pPattern) - 1
			
			char = pPattern[i]
			
			If (char = Asc("^")) AndAlso (i = 0) Then
				
				bRet = -1
				
				If Len(pPattern) = 1 Then Return pCharacter = char
				
			ElseIf inRange Then
				
				inRange = 0
				
				If ((lastChar <= pCharacter) AndAlso (pCharacter <= char)) OrElse (pCharacter = char) Then 
					Return Not bRet
				EndIf  
			
			ElseIf (char = Asc("-")) AndAlso (i > 0) AndAlso (i < Len(pPattern) - 1) Then
				
				inRange = -1
				Continue For
				
			ElseIf pCharacter = char Then
				
				Return Not bRet		
				
			EndIf
			
			lastChar = char
			
		Next
		
		Return bRet
	'}	
	End Function
	
	
	Function StrInPattern(	ByRef pCharacter As Const String											,_
									ByRef pPattern As Const String											)_
									As Integer
	'{	
		Return StrInPattern( pCharacter[0], pPattern )
	'}	
	End Function
	
	
	Function StrCountChars(	ByRef pString As Const String												,_
									ByRef pPattern As Const String											)_
									As Integer
	'{	
		Dim As Integer iCount = 0
		
		For i As Integer = 0 To Len(pString) - 1
			If StrInPattern(pString[i], pPattern) Then iCount += 1
		Next
		
		Return iCount	
	'}	
	End Function
	
	
	Function StrReplaceChars(	ByRef pString As Const String											,_
										ByRef pPattern As Const String										,_
										ByVal pReplacer As Const StrCharReplacer							)_
										As String
	'{	
		Dim As String sRet
		Dim As UByte code
		
		For i As Integer = 0 To Len(pString) - 1
			code = pString[i]
			If StrInPattern(code, pPattern) Then
				sRet += pReplacer(code, i + 1)
			Else
				sRet += Chr(code)
			EndIf
		Next
		
		Return sRet
	'}	
	End Function
	
	
	Function StrReplaceChars(	ByRef pString As Const String											,_
										ByRef pPattern As Const String										,_
										ByRef pReplaceWith As Const String									)_
										As String
	'{	
		Dim As String sRet
		Dim As UByte code
		
		For i As Integer = 0 To Len(pString) - 1
			code = pString[i]
			If StrInPattern(code, pPattern) Then
				sRet += pReplaceWith
			Else
				sRet += Chr(code)
			EndIf
		Next
		
		Return sRet
	'}	
	End Function
	
	
	Function StrRemoveChars(	ByRef pString As Const String											,_
										ByRef pPattern As Const String										)_
										As String
	'{	
		Dim As String sRet
		Dim As UByte code
		
		For i As Integer = 0 To Len(pString) - 1
			code = pString[i]
			If Not StrInPattern(code, pPattern) Then sRet += Chr(code)
		Next
		
		Return sRet
	'}	
	End Function
	
	
	Namespace StringHelpers
		
		Const MaxParts As Integer = 100000
		
		Static Shared part(0 To MaxParts - 1) As Integer
		
	End Namespace
	
	
	Function StrExplode(	ByRef pString As Const String													,_
								ByRef pDelimiter As Const String												,_
								pResult() As String																,_
								ByVal pCompare As Const CompareMethod = BinaryCompare					)_
								As Integer
	'{	
		Dim As Integer iParts = 0, iPos
		Dim As Const Integer iDelimiterLength = Len(pDelimiter)
		Dim As String sString, sDelimiter
		
		If pCompare = TextCompare Then
			sString = LCase(pString)
			sDelimiter = LCase(pDelimiter)
		Else
			sString = pString
			sDelimiter = pDelimiter
		EndIf
		
		iPos = 1 - iDelimiterLength
		
		Do
			
			iPos = InStr(iPos + iDelimiterLength, sString, sDelimiter)
			
			If iPos = 0 Then Exit Do
			
			StringHelpers.part(iParts) = iPos
			iParts += 1
			
		Loop
		
		StringHelpers.part(iParts) = Len(pString) + 1
		
		ReDim pResult(0 To iParts) As String
		Dim As Integer iStart = 1
		
		For i As Integer = 0 To iParts
			pResult(i) = Mid(pString, iStart, StringHelpers.part(i) - iStart)
			iStart = StringHelpers.part(i) + iDelimiterLength
		Next
		
		Return iParts + 1
	'}	
	End Function
	
	
	Function StrImplode(	pArray() As String																,_
								ByRef pGlue As Const String = " "											)_
								As String
	'{	
		Dim As String sRet
		
		For i As Integer = LBound(pArray) To UBound(pArray)
			sRet += pArray(i)
			If i < UBound(pArray) Then sRet += pGlue
		Next
		
		Return sRet
	'}	
	End Function
	
	
	Function StrSplitByChar(	ByRef pString As Const String											,_
										ByRef pPattern As Const String										,_
										pResult() As String														)_
										As Integer
	'{	
		Dim As Integer iParts = 0, code
		
		For i As Integer = 0 To Len(pString) - 1
			code = pString[i]
			If StrInPattern(code, pPattern) Then
				StringHelpers.part(iParts) = i + 1
				iParts += 1
			EndIf
		Next
		
		StringHelpers.part(iParts) = Len(pString) + 1
		
		ReDim pResult(0 To iParts) As String
		Dim As Integer iStart = 1
		
		For i As Integer = 0 To iParts
			pResult(i) = Mid(pString, iStart, StringHelpers.part(i) - iStart)
			iStart = StringHelpers.part(i) + 1
		Next
		
		Return iParts + 1
	'}	
	End Function
	
	
	Function StrLines(	ByRef pString As Const String													,_
								pResult() As String																)_
								As Integer
	'{	
		Dim As Integer iParts = 0, code
		
		For i As Integer = 0 To Len(pString) - 1
			code = pString[i]
			If (code = C_CR) OrElse (code = C_LF) Then
				StringHelpers.part(iParts) = i
				iParts += 1
				If (code = C_CR) AndAlso (i < Len(pString) - 1) AndAlso (pString[i + 1] = C_LF) Then i += 1
			EndIf
		Next
		
		StringHelpers.part(iParts) = Len(pString) + 1
		
		ReDim pResult(0 To iParts) As String
		Dim As Integer iStart = 1
		
		For i As Integer = 0 To iParts
			pResult(i) = Mid(pString, iStart, StringHelpers.part(i) - iStart)
			iStart = StringHelpers.part(i) + 2
			If (i < iParts) AndAlso (pString[iStart - 2] = C_CR) AndAlso _
											(pString[iStart - 1] = C_LF) Then iStart += 1
		Next
		
		Return iParts + 1
	'}	
	End Function
	
	
	Function StrExpandTabs(	ByRef pString As Const String												,_
									ByVal pTabSize As Const Integer = 8										)_
									As String
	'{	
		Dim As String sRet
		Dim As Integer iColumn, iNumSpaces, code
		Dim As Integer bChanges = 0
		
		For i As Integer = 1 To Len(pString)
			
			code = pString[i - 1]
			
			Select Case As Const code
				
				Case C_TAB
					iNumSpaces = pTabSize - (iColumn Mod pTabSize)
					If Not bChanges Then
						bChanges = -1
						sRet = Left(pString, i - 1)
					EndIf
					sRet += String(iNumSpaces, " ")
				
				Case C_CR
					iColumn = 0
					If (i <= Len(pString)) AndAlso (pString[i] = C_LF) Then i += 1
					GoTo AppendChar
				
				Case C_LF
					iColumn = 0
					GoTo AppendChar
				
				Case Else
					iColumn += 1
				AppendChar:
					If bChanges Then sRet += Chr(code)
					
			End Select
		Next
		
		If bChanges Then Return sRet
		
		Return pString
	'}	
	End Function
	
	
	Function StrLike(	ByRef pString As Const String														,_
							ByRef pPattern As Const String													,_
							ByVal pCompare As Const CompareMethod = BinaryCompare						)_
							As Integer
	'{	
		Dim As String sString, sPattern
		
		If pCompare = TextCompare Then
			sString = LCase(pString)
			sPattern = LCase(pPattern)
		Else
			sString = pString
			sPattern = pPattern
		EndIf
		
		Dim As Integer inBrackets = 0
		
		For i As Integer = 0 To Len(pPattern) - 1
			Select Case As Const pPattern[i]
				
				Case Asc("[")
					If inBrackets Then Return 0
					inBrackets = -1
				
				Case Asc("]")
					If Not inBrackets Then Return 0
					inBrackets = -1
					
			End Select
		Next
		
		Dim As Integer f = 0, sc, pc, notInClass, anyMatch
		
		For i As Integer = 0 To Len(sPattern) - 1
			pc = sPattern[i]
			Select Case As Const pc
				
				Case Asc("*")
					If i = (Len(sPattern) - 1) Then Return -1
					For j As Integer = f To Len(sString) - 1
						If StrLike(Mid(sString, j + 1), Mid(sPattern, i + 2)) Then Return -1
					Next 
					Return 0
				
				Case Asc("?")
					If f = Len(sString) Then Return 0
					f += 1
				
				Case Asc("#")
					If f = Len(sString) Then Return 0
					sc = sString[f]
					if (sc < Asc("0")) OrElse (sc > Asc("9")) Then Return 0
					f += 1
				
				Case Asc("[")
					If f = Len(sString) Then Return 0
					sc = sString[f]
					f += 1
					i += 1
					notInClass = 0
					If sPattern[i] = Asc("^") Then
						notInClass = 1
						i += 1
					EndIf
					anyMatch = 0
					Do
						pc = sPattern[i]
						If pc = Asc("]") Then Exit Do
						If (anyMatch = 0) AndAlso (sc = pc) Then anyMatch = 1
						i += 1 
					Loop
					If (anyMatch Xor notInClass) = 0 Then Return 0
				
				Case Else
					If f = Len(sString) Then Return 0
					sc = sString[f]
					If sc <> pc Then Return 0
					f += 1
				
			End Select
		Next
		
		If f < Len(sString) Then Return 0
		
		Return -1
	'}	
	End Function
	
	
	Function StrSubstring(	ByRef pString As Const String												,_
									ByVal pStart As Integer														,_
									ByVal pLength As Integer = 0												)_
									As String
	'{	
		Dim As Const Integer pStringLength = Len(pString)
		
		If pStringLength = 0 Then Return ""
		
		If pLength = 0 Then pLength = pStringLength
		
		If pStart < 0 Then pStart += pStringLength + 1
		If pStart < 1 Then pStart = 1
		If pStart > pStringLength Then Return ""
		
		If pLength < 0 Then pLength += pStringLength - pStart + 1
		
		If pStart + pLength > pStringLength Then pLength = pStringLength - pStart + 1
		
		If pLength < 1 Then Return ""
		
		Return Mid(pString, pStart, pLength)
	'}	
	End Function
	
	
	Function StrWordwrap(	ByRef pString As Const String												,_
									ByVal pColumnWidth As Const Integer = 80								,_
									ByRef pLineBreak As Const String = !"\n"								,_
									ByVal pCutWords As Const Integer = 0									)_
									As String
	'{
		Dim As Const Integer pStringLength = Len(pString), pLineBreakLength = Len(pLineBreak)
		
		If (pStringLength = 0) OrElse (pColumnWidth < 1) Then Return ""
		
		Dim As String sRet
		Dim As Integer iLastStart = 0, iLastSpace = 0
		
		If (pLineBreakLength = 1) AndAlso (pCutWords = 0) Then
			
			sRet = pString
			
			For i As Integer = 0 To pStringLength - 1
				If pString[i] = pLineBreak[0] Then
					iLastStart = i
					iLastSpace = i
				ElseIf pString[i] = 32 Then
					If i - iLastStart >= pColumnWidth Then
						sRet[i] = pLineBreak[0]
						iLastStart = i
					EndIf
					iLastSpace = i
				ElseIf (i - iLastStart >= pColumnWidth) OrElse (iLastStart <> iLastSpace) Then
					sRet[iLastSpace] = pLineBreak[0]
					iLastStart = iLastSpace
				EndIf
			Next
			
		Else
			
			sRet = String(pStringLength + (pStringLength / pColumnWidth + 1) * pLineBreakLength + 1, 32)
			
			Dim As Integer iNewLength = 0, i
			
			Dim As ZString Const Pointer 	ptrString = StrPtr(pString)			,_
													ptrRet = StrPtr(sRet)					,_
													ptrLineBreak = StrPtr(pLineBreak)
			 
			For i = 0 To pStringLength - 1
				
				If (pString[i] = pLineBreak[0]) AndAlso _
					(i + pLineBreakLength < pStringLength) AndAlso _
					(StrnCmp(ptrString + i, ptrLineBreak, pLineBreakLength) = 0) Then
					
					memcpy ptrRet + iNewLength, ptrString + iLastStart, i - iLastStart + pLineBreakLength
					iNewLength += i - iLastStart + pLineBreakLength
					i += pLineBreakLength - 1
					iLastStart = i + 1
					iLastSpace = i + 1
					 
				ElseIf pString[i] = 32 Then
					
					If i - iLastStart >= pColumnWidth Then
						memcpy ptrRet + iNewLength, ptrString + iLastStart, i - iLastStart
						iNewLength += i - iLastStart
						memcpy ptrRet + iNewLength, ptrLineBreak, pLineBreakLength
						iNewLength += pLineBreakLength
						iLastStart = i + 1
					EndIf
					
					iLastSpace = i
				
				ElseIf (i - iLastStart >= pColumnWidth) AndAlso _
						 pCutWords AndAlso (iLastStart >= iLastSpace) Then
						 
					memcpy ptrRet + iNewLength, ptrString + iLastStart, i - iLastStart
					iNewLength += i - iLastStart
					memcpy ptrRet + iNewLength, ptrLineBreak, pLineBreakLength
					iNewLength += pLineBreakLength
					iLastStart = i
					iLastSpace = i   
				
				ElseIf (i - iLastStart >= pColumnWidth) AndAlso (iLastStart < iLastSpace) Then
					
					memcpy ptrRet + iNewLength, ptrString + iLastStart, iLastSpace - iLastStart
					iNewLength += iLastSpace - iLastStart
					memcpy ptrRet + iNewLength, ptrLineBreak, pLineBreakLength
					iNewLength += pLineBreakLength
					iLastSpace += 1
					iLastStart = iLastSpace

				EndIf
			Next
			
			If iLastStart <> i Then
				memcpy ptrRet + iNewLength, ptrString + iLastStart, i - iLastStart
				iNewLength += i - iLastStart
			EndIf
			
			sRet = Left(sRet, iNewLength)
			
		EndIf
		
		Return sRet
	'}
	End Function
	
	
	
	
End Namespace

#Undef C_TAB
#Undef C_CR
#Undef C_LF